package chapter11;

import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author eric
 * Descrption: 开发一个这样的服务器，
 * 它可以处理来自多个客户端的请求（即Request）。为了不丢失客户端的请求，它要维护一个缓冲区，客户的请求会先储存至缓冲区中，
 * 而服务器会从缓冲区中取出请求并执行，如果缓冲区中没有请求，则服务器就等待，直到接收到通知有新的请求存入缓冲区中，服务器再重整旗鼓进行请求的执行。
 * 使用Guarded Suspension模式
 */
public class RequestQueue {

    /**
     * 缓冲区最大个数
     */
    public static final Integer MAX_LIMIT = 10;
    private Queue<Request> queue = new ArrayBlockingQueue<>(MAX_LIMIT);
    ReentrantLock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    public Request get() {
        Request request = null;
        lock.lock();
        try {
            while (queue.isEmpty()) {
                condition.await();
            }
            request = queue.poll();
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
            condition.signalAll();
        } finally {
            lock.unlock();
        }

        return request;
    }

    public void Request(Request request) {
        lock.lock();
        try {
            while (queue.size() >= MAX_LIMIT) {
                condition.await();
            }
            queue.add(request);
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

}
